package com.example.demo.service.impl;

import com.example.demo.entity.*;
import com.example.demo.repository.BookMapper;
import com.example.demo.repository.BorrowMapper;
import com.example.demo.repository.UserMapper;
import com.example.demo.service.BookService;
import org.apache.commons.lang3.time.DateUtils;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;


@Service
public class BookServiceImpl implements BookService {

    @Autowired
    BookMapper bookMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    UserService userService;

    @Autowired
    BorrowMapper borrowMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;


    @Override
    public List<Book> findAllBooks() {
        return bookMapper.selectAll();
    }

    @Transactional
    public Boolean borrowBookById(String bookid, String username) {

        Borrow borrow = borrowMapper.selectOne(bookid, username);
        //同一本书 一个人只能借一次
        if (borrow != null) {
            return false;
        }

        //找这个人 如果不是普通用户 而是游客 那么获取不到
        User user = new User();
        try {
            user = userService.selectUserIsExisted(username).get(0);
        } catch (IndexOutOfBoundsException e) {
            return false;
        }
        //每人最多借5本书
        if (user.getBorrownum() >= 5) {
            return false;
        }

        //找这本书
        BookExample bookExample1 = new BookExample();
        BookExample.Criteria criteria1 = bookExample1.createCriteria();
        criteria1.andBookidEqualTo(bookid);
        Book book = bookMapper.selectByExample(bookExample1).get(0);

        //如果没书了，不能再借了
        if (book.getLeftnum() == 0) {
            return false;
        }

        Integer newBorrowNum = user.getBorrownum() + 1;
        user.setBorrownum(newBorrowNum);
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andUsernameEqualTo(username);
        //书本重新更新数据 剩余-1
        Integer newLeftNum = book.getLeftnum() - 1;
        book.setLeftnum(newLeftNum);
        BookExample bookExample2 = new BookExample();
        BookExample.Criteria criteria2 = bookExample2.createCriteria();
        criteria2.andBookidEqualTo(bookid);

        userMapper.updateByExampleSelective(user, userExample);
        bookMapper.updateByExample(book, bookExample2);

        //到此为止，如果都成了，那么借阅信息表 需插入相关信息
        borrowMapper.insertOne(bookid, username, DateUtils.addDays(new Date(), 30), book.getBookname());

        //借书成功后 该生借书总数+1 利用redis存储
        Object object = stringRedisTemplate.opsForHash().get("countMap", username);
        //如果是第一次借书 那么总量初始为1
        if (object == null) {
            stringRedisTemplate.opsForHash().put("countMap", username, String.valueOf(1));
        } else {
            //否则 累加借书总数
            int count = Integer.valueOf((String) object);
            stringRedisTemplate.opsForHash().put("countMap", "user", String.valueOf(count + 1));

        }
        return true;
    }

    @Override
    public List<Borrow> findAllBooksBorrowed(String username) {
        return borrowMapper.selectAllByUsername(username);
    }

    @Override
    @Transactional
    public Boolean returnBook(String bookid, String username) {

        User user = userService.selectUserIsExisted(username).get(0);

        BookExample bookExample1 = new BookExample();
        BookExample.Criteria criteria1 = bookExample1.createCriteria();
        criteria1.andBookidEqualTo(bookid);
        Book book = bookMapper.selectByExample(bookExample1).get(0);

        if (user == null || book == null) {
            return false;
        }

        //开始归还
        user.setBorrownum(user.getBorrownum() - 1);
        book.setLeftnum(book.getLeftnum() + 1);

        //更改状态
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andUsernameEqualTo(username);

        BookExample bookExample2 = new BookExample();
        BookExample.Criteria criteria2 = bookExample2.createCriteria();
        criteria2.andBookidEqualTo(bookid);

        userMapper.updateByExampleSelective(user, userExample);
        bookMapper.updateByExample(book, bookExample2);

        borrowMapper.deleteOne(bookid, username);

        return true;
    }

    @Override
    public List<PopularBook> findAllPopularBooks(Integer popularNum) {
        return borrowMapper.showPopularBooks(popularNum);
    }

    @Override
    public List<Book> getBooksByKeyword(Book book, String keyword) {
        return bookMapper.selectAllByKeyword(book, keyword);
    }

    @Override
    @Transactional
    public void checkBookExpireStatus(List<Borrow> list) {
        //今天的时间
        Date currentDate = new Date();
        String username = list.get(0).getUsername();
        int oweFee = 1; //每欠一天 给1$

        for (Borrow borrow : list) {
            String bookname = borrow.getBookname();
            //过期的时间 是否在今天之后
            //如果返回值大于0 代表确实没过期
            //否则 就算过期了
            Date expireDate = borrow.getExpiredate();
            int flag = expireDate.compareTo(currentDate);
            int daysBetween = (int) ((expireDate.getTime() - currentDate.getTime()) / (1000 * 3600 * 24));
            if (flag > 0) {
                //计算快5天内 就过期了
                //dayB 返回的是相隔的天数 整数！如果是0 说明过期时间不到24小时了
                //newStatus=1 代表快要过期 0代表没有 2代表已经过期
                if (daysBetween <= 4) {
                    borrowMapper.updateExpireStatus(1, username, bookname);
                }
            } else {
                //如果欠费 欠费的
                daysBetween = (-1) * daysBetween;
                borrowMapper.updateExpireStatus(2, username, bookname);
                borrowMapper.updateOweFees(daysBetween * oweFee, username, bookname);
            }
        }
    }
}
